package com.cgs.mongo.delegate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.mongodb.Block;
import com.mongodb.Function;
import com.mongodb.client.ChangeStreamIterable;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoIterable;
import com.mongodb.client.model.Collation;
import com.mongodb.client.model.changestream.ChangeStreamDocument;
import com.mongodb.client.model.changestream.FullDocument;
import com.mongodb.lang.Nullable;
import org.bson.BsonDocument;
import org.bson.BsonTimestamp;
import org.bson.Document;

import java.util.Collection;
import java.util.Map;
import java.util.Spliterator;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import static com.cgs.mongo.utils.WrapperUtils.asBsonDocument;

public class ChangeStreamIterableWrapper<TDocument> implements ChangeStreamIterable<TDocument> {

    private ChangeStreamIterable<TDocument> delegate;

    public ChangeStreamIterableWrapper(ChangeStreamIterable<TDocument> delegate) {
        this.delegate = delegate;
    }

    @Override
    public ChangeStreamIterable<TDocument> fullDocument(FullDocument fullDocument) {
        return delegate.fullDocument(fullDocument);
    }

    @Override
    public ChangeStreamIterable<TDocument> resumeAfter(BsonDocument resumeToken) {
        return delegate.resumeAfter(resumeToken);
    }
    public ChangeStreamIterable<TDocument> resumeAfter(Map<String, Object> resumeToken) throws JsonProcessingException {
        return delegate.resumeAfter(asBsonDocument(resumeToken));
    }

    @Override
    public ChangeStreamIterable<TDocument> batchSize(int batchSize) {
        return delegate.batchSize(batchSize);
    }

    @Override
    public ChangeStreamIterable<TDocument> maxAwaitTime(long maxAwaitTime, TimeUnit timeUnit) {
        return delegate.maxAwaitTime(maxAwaitTime, timeUnit);
    }

    public ChangeStreamIterable<TDocument> maxAwaitTime(long maxAwaitTime) {
        return delegate.maxAwaitTime(maxAwaitTime, TimeUnit.SECONDS);
    }

    @Override
    public ChangeStreamIterable<TDocument> collation(Collation collation) {
        return delegate.collation(collation);
    }

    @Override
    public <TDocument> MongoIterable<TDocument> withDocumentClass(Class<TDocument> clazz) {
        return delegate.withDocumentClass(clazz);
    }

    @Override
    public ChangeStreamIterable<TDocument> startAtOperationTime(BsonTimestamp startAtOperationTime) {
        return delegate.startAtOperationTime(startAtOperationTime);
    }

    @Override
    public MongoCursor<ChangeStreamDocument<TDocument>> iterator() {
        return delegate.iterator();
    }

    @Override
    @Nullable
    public ChangeStreamDocument<TDocument> first() {
        return delegate.first();
    }

    @Override
    public <U> MongoIterable<U> map(Function<ChangeStreamDocument<TDocument>, U> mapper) {
        return delegate.map(mapper);
    }

    @Override
    @Deprecated
    public void forEach(Block<? super ChangeStreamDocument<TDocument>> block) {
        delegate.forEach(block);
    }

    @Override
    public <A extends Collection<? super ChangeStreamDocument<TDocument>>> A into(A target) {
        return delegate.into(target);
    }

    @Override
    public void forEach(Consumer<? super ChangeStreamDocument<TDocument>> action) {
        delegate.forEach(action);
    }

    @Override
    public Spliterator<ChangeStreamDocument<TDocument>> spliterator() {
        return delegate.spliterator();
    }
}
